package com.chang.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chang.common.constant.WareConstant;
import com.chang.common.utils.PageUtils;
import com.chang.common.utils.Query;
import com.chang.ware.entity.PurchaseDetailEntity;
import com.chang.ware.entity.PurchaseEntity;
import com.chang.ware.mapper.PurchaseDao;
import com.chang.ware.service.PurchaseDetailService;
import com.chang.ware.service.PurchaseService;
import com.chang.ware.service.WareSkuService;
import com.chang.ware.vo.MergeVo;
import com.chang.ware.vo.PurchaseDoneVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    PurchaseDetailService purchaseDetailService;

    @Autowired
    WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );
        return new PageUtils(page);
    }

    @Override
    public PageUtils queryUnReceiveList(Map<String, Object> params) {
        LambdaQueryWrapper<PurchaseEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PurchaseEntity::getStatus, 0).or().eq(PurchaseEntity::getStatus, 1);
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                lambdaQueryWrapper
        );
        return new PageUtils(page);
    }

    /*
     * @Author Chang
     * @Date 2024/3/26 17:17
     * @Description 这里的逻辑是如果传递过来的purchaseId有值,代表是人为合并采购单,如果为空,则是自动定时合并的
     * @Param [mergeVo]
     * @Return com.chang.common.utils.PageUtils
     * @Since version 1.0
     */
    @Transactional
    @Override
    public void merge(MergeVo mergeVo) {
        Long purchaseId = mergeVo.getPurchaseId();
        if (purchaseId == null) {
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        Long finalPurchaseId = purchaseId; // lambda 表达式中使用的变量应为 final 或有效 final 这里需要一个转换
        List<PurchaseDetailEntity> purchaseDetailEntityList = mergeVo.getItems().stream()
                // 正在采购以及采购完成的就不能重新参与合并整单了
                .filter(item -> {
                    Integer status = purchaseDetailService.getById(item).getStatus();
                    return status != WareConstant.PurchaseDetailStatusEnum.RECEIVE.getCode() && status != WareConstant.PurchaseDetailStatusEnum.FINISHED.getCode();
                })
                .map(item -> {
                    PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                    purchaseDetailEntity.setId(item);
                    // purchaseDetailEntity.setWareId(); // TODO 这里前端没有传递过来仓库id
                    purchaseDetailEntity.setPurchaseId(finalPurchaseId);
                    purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
                    return purchaseDetailEntity;
                }).toList();
        purchaseDetailService.updateBatchById(purchaseDetailEntityList);
    }

    /*
     * @Author Chang
     * @Date 2024/3/27 11:08
     * @Description 有人员认领采购单的时候改变采购单以及单中采购项的状态
     * @Param [purchaseIds]
     * @Return void
     * @Since version 1.0
     */
    @Override
    public void received(List<Long> purchaseIds) {

        // 确认当前采购项是否为已分配状态
        List<PurchaseEntity> purchaseEntityList = purchaseIds.stream()
                .map(this::getById)
                .filter(item -> item.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) // 只有分配状态才能被领取
                .toList();

        // 改变采购项状态,
        // 预存采购单id
        // List<Long> list = new ArrayList<>();

        purchaseEntityList.forEach(item -> {
            item.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
            updateById(item); // 修改采购单状态后保存
            LambdaQueryWrapper<PurchaseDetailEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PurchaseDetailEntity::getPurchaseId, item.getId());
            purchaseDetailService.getBaseMapper().selectList(lambdaQueryWrapper)
                    .forEach(purchaseDetailEntity -> {
                        purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.RECEIVE.getCode());
                        purchaseDetailService.updateById(purchaseDetailEntity); // 修改采购项状态后保存
                    });

            // 多个采购项对应相同采购单时候只需要修改一次状态就好了,但是如果采购项是杂乱的呢? 我这边用了一个集合预存判断来解决 后续: 这里我理解错了，以为传递的是采购项id
/*            Long purchaseId = item.getPurchaseId();
            if (!list.contains(purchaseId)) {
                // 改变各个采购项对应采购单的状态
                PurchaseEntity purchaseEntity = new PurchaseEntity();
                purchaseEntity.setId(purchaseId);
                purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
                this.updateById(purchaseEntity);
                list.add(purchaseId);
            }*/
        });

    }

    /*
     * @Author Chang
     * @Date 2024/3/27 16:12
     * @Description 采购完成,修改状态  注意,需要所有采购项完成,采购单才算做完成
     * @Param [purchaseDoneVo]
     * @Return void
     * @Since version 1.0
     */
    @Override
    public void purchaseDone(PurchaseDoneVo doneVo) {
        Long purchaseId = doneVo.getId();
        PurchaseEntity isExistence = getById(purchaseId);
        if (isExistence == null || isExistence.getStatus() != WareConstant.PurchaseStatusEnum.RECEIVE.getCode()) {
            System.out.println("采购单不存在或采购已完成");
            return;
        }

        // 改变采购项状态
        List<PurchaseDetailEntity> purchaseDetailList = doneVo.getItems().stream()
                // 这里需要进行过滤,防止出现传过来的采购项不属于当前采购单的情况
                .filter(item -> Objects.equals(purchaseDetailService.getById(item.getItemId()).getPurchaseId(), doneVo.getId()))
                .map(item -> {
                    PurchaseDetailEntity purchaseDetail = new PurchaseDetailEntity();
                    purchaseDetail.setStatus(item.getStatus());
                    purchaseDetail.setId(item.getItemId());
                    return purchaseDetail;
                }).toList();

        purchaseDetailService.updateBatchById(purchaseDetailList);

        // 改变采购单状态
        // anyMatch-> 一个为ture 直接返回true
        boolean errorStatus = doneVo.getItems().stream()
                .anyMatch(item -> {
                    if (item.getStatus() != WareConstant.PurchaseDetailStatusEnum.HAS_ERROR.getCode()) {
                        Long purchaseDetailId = item.getItemId();
                        PurchaseDetailEntity purchaseDetailEntity = purchaseDetailService.getById(purchaseDetailId);
                        // 将成功采购的进行入库
                        // 传入三个参数,采购商品id 仓库id,采购商品数量,
                        wareSkuService.addStock(purchaseDetailId, purchaseDetailEntity.getWareId(), purchaseDetailEntity.getSkuNum());
                        return false;
                    } else return true;
                });

        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setStatus(errorStatus ? WareConstant.PurchaseStatusEnum.HAS_ERROR.getCode() : WareConstant.PurchaseStatusEnum.FINISHED.getCode());

        updateById(purchaseEntity);

    }

}